"use strict";
import {
  useState,
  useEffect,
  forwardRef,
  ForwardedRef,
  useImperativeHandle,
  ReactElement,
} from "react";
import { Form, Input, Select, DatePicker, Checkbox, Button, Space } from "antd";
// import { DataOption, DataSource, IProps, PickerFormat, Types } from "./search-form.d";
import {
  DataOption, DataSource, IProps, PickerFormat, Types,
  FormatValues, RangePickerType, FormatRangePicker,
} from "./search-form.d";
/*
 * 组件注释
 * create by wuqiong
 * creation time 2021/05/19
 * 水平布局 简易的sreach 组件
 * */
const datesOption = ["date", "datePicker", "rangePicker"];
const checkboxsOption = ["checkbox"];
const { Option } = Select;
const { RangePicker } = DatePicker;

const getConf = (dataSource: DataSource[], option: string[]) =>
  dataSource.filter((item: DataSource) =>
    option.includes(item.type as string)
  ) || [];

const Index = forwardRef((props: IProps, ref: ForwardedRef<unknown>) => {
  const { onFinish, dataSource, btnText, isReset, automatic, ...otherProp } =
    props;
  const [initialValues] = useState(props.initialValues);
  const [dates, setDates] = useState<DataSource[]>(
    getConf(dataSource, datesOption)
  );
  const [checkboxs, setCheckboxs] = useState<DataSource[]>(
    getConf(dataSource, checkboxsOption)
  );
  const [form] = Form.useForm();

  const getFormItemHtml = (data: DataSource, isLast: boolean): ReactElement => {
    const {
      name,
      label,
      placeholder,
      type = "input",
      option,
      width = 180,
      text,
      element,
      fieldNames,
      ...other
    } = data;

    const formItemHtml = (type: Types) => {
      switch (type) {
        case "select":
          return (
            <Select
              style={{ width }}
              allowClear
              placeholder={
                placeholder
                  ? placeholder
                  : label
                    ? `请选择${label}`
                    : "请选择..."
              }
              dropdownMatchSelectWidth={false}
              {...other}>
              {(option as DataOption[]).map((child: DataOption) => {
                let value = child.key;
                let label = child.value;
                if (fieldNames && fieldNames?.value in child) {
                  value = (child as any)[fieldNames.value];
                  label = (child as any)[fieldNames.label];
                }
                return (
                  <Option value={value} key={value}>
                    {label}
                  </Option>
                );
              })}
            </Select>
          );

        case "date":
        case "datePicker":
          return (
            <DatePicker
              style={{ width, borderRadius: 5 }}
              allowClear
              placeholder={
                placeholder
                  ? placeholder
                  : label
                    ? `请选择${label}`
                    : "请选择时间"
              }
              {...other}
            />
          );

        case "rangePicker":
          const _placeholder =
            Array.isArray(placeholder) && placeholder.length
              ? placeholder
              : ["开始时间", "结束时间"];

          return (
            <RangePicker
              style={{ width: data.width || 253, borderRadius: 5 }}
              allowClear
              placeholder={_placeholder as [string, string] | undefined}
              {...other}
            />
          );

        case "checkbox":
          return <Checkbox>{text as string}</Checkbox>;

        default:
          return (
            <Input
              allowClear
              style={{ width, borderRadius: 5 }}
              placeholder={
                placeholder
                  ? placeholder
                  : label
                    ? `请输入${label}`
                    : "请输入..."
              }
              {...other}
            />
          );
      }
    };

    // 最后一个单元并且没有搜索、重置按钮时 不展示
    // const showMargin = isLast && automatic && !isReset;

    return (
      <Form.Item
        // style={{ marginRight: showMargin ? 0 : "10px" }}
        style={{ marginRight: 0 }}
        key={name} name={name} label={label}
        {...(type === "checkbox" ? { valuePropName: "checked" } : {})}>
        {element ?? formItemHtml(type)}
      </Form.Item>
    );
  };

  // 因数据中有时间、双选以及其他特殊数据，因此需要format数据
  const formatValues = (values: { [x: string]: FormatValues }) => {
    let newVals: { [x: string]: FormatValues } = {};
    // 去除空值
    for (let key in values) {
      newVals[key] = window.isEmpty(values[key]) ? undefined : values[key];
    }

    if (dates.length) {
      dates.forEach((item: DataSource) => {
        if (newVals[item.name]) {
          let timeDate = null;
          let defaultFormat = "YYYY-MM-DD"
          if (item.picker) {
            defaultFormat = PickerFormat[item.picker]
          }

          let format = item.format as string || defaultFormat;

          if (item.notUseFormat) {
            format = defaultFormat
          }

          if (item.type === "rangePicker") {
            timeDate = (newVals[item.name] as RangePickerType).map((child?: moment.Moment) => {
              return child
                ? child.format(format)
                : undefined;
            }) as FormatRangePicker;
          } else {
            timeDate = newVals[item.name] ? (newVals[item.name] as moment.Moment).format(format) as string : undefined;
          }

          newVals = {
            ...newVals,
            [item.name]: timeDate,
          };
        }
      });
    }

    if (checkboxs.length) {
      checkboxs.forEach(item => {
        newVals = {
          ...newVals,
          [item.name]: Number(newVals[item.name]) || undefined,
        };
      });
    }
    return newVals;
  }

  // 提交数据
  const _onFinish = (values: { [x: string]: FormatValues }): void => {
    const formatValue = formatValues(values)
    onFinish && onFinish(formatValue);
  };

  // 重置
  const reset = (): void => {
    form.resetFields();
    const formatValue = formatValues(initialValues);
    onFinish && onFinish(formatValue);
  };

  // 值改变以后触发finish
  const onFieldsChange = (): void => {
    if (!automatic) return;
    const values = form.getFieldsValue();
    _onFinish(values)
  };

  useEffect(() => {
    setDates(getConf(dataSource, datesOption));
    setCheckboxs(getConf(dataSource, checkboxsOption));
  }, [dataSource]);

  useImperativeHandle(ref, () => ({ ...form }));

  return (
    <div className={"searchForm"}>
      <Form
        form={form}
        name="search"
        layout="inline"
        onFinish={window.debounce(_onFinish, 500, true)}
        {...automatic ? { onFieldsChange: window.debounce(onFieldsChange, 500) } : {}}
        {...otherProp}>
        <Space size={[10, 16]} wrap>
          {dataSource.map((item: DataSource, idx: number, self: DataSource[]) => getFormItemHtml(item, self.length - 1 === idx))}

          {(!automatic || isReset) && <Form.Item style={{ marginRight: 0 }}>
            <Space>
              {!automatic ? (
                <Button type="primary" htmlType="submit">{btnText}</Button>
              ) : null}
              {isReset ? (
                <Button type="primary" onClick={() => reset()}>重置</Button>
              ) : null}
            </Space>
          </Form.Item>}
        </Space>
      </Form>
    </div>
  );
});

export default Index;
Index.defaultProps = {
  isReset: false, //重置按钮
  automatic: false, //自动提交
  onFinish: (values: unknown) => console.log(values),
  dataSource: [
    {
      label: "label",
      name: "select",
      placeholder: "placeholder",
      type: "select", // input
      option: [{ key: "key", value: "value" }],
      fieldNames: { label: "label", value: "value", options: "options" },
    },
    {
      label: "label",
      name: "time",
      placeholder: "placeholder",
      type: "date",
      picker: "year",
      format: "YYYY-MM-DD",
    },
    {
      text: "label",
      name: "checkbox",
      type: "checkbox",
      // element:  element可以传入组件自定义功能
    },
  ],
  btnText: "搜索",
};
